Skip to content

Fix concurrent map iteration and write panic in AppRefTracker - #1844

Open
somaz94 wants to merge 3 commits into
carvel-dev:developfrom
somaz94:fix/reftracker-concurrent-map-race
Open

somaz94 wants to merge 3 commits into
carvel-dev:developfrom
somaz94:fix/reftracker-concurrent-map-race

Conversation

@somaz94

@somaz94 somaz94 commented Jul 15, 2026

Copy link
Copy Markdown

What this PR does / why we need it:

AppRefTracker.AppsForRef and RefsForApp returned the internal map by
reference. Callers such as SecretHandler.enqueueAppsForUpdate and
ConfigMapHandler.enqueueAppsForUpdate iterate that map after the tracker lock
is released, so a concurrent ReconcileRefs / RemoveAppFromAllRefs writing the
same map crashes kapp-controller with fatal error: concurrent map iteration and map write. This reproduces on large clusters with thousands of
namespaces/secrets under continuous reconciliation.

Both methods now return a shallow copy of the RefKey set while holding the lock,
so callers iterate a private map and never race the writers. The two callers
only iterate the result (read-only), so returning a copy is behavior-preserving.

Which issue(s) this PR fixes:

Fixes #1843

Does this PR introduce a user-facing change?

Fix panic ("concurrent map iteration and map write") in AppRefTracker that could
crash kapp-controller on large clusters under high reconciliation concurrency.

Additional Notes for your reviewer:

Added two regression tests in pkg/reftracker/ref_tracker_race_test.go
(concurrent read+iterate against a concurrent writer, for both AppsForRef and
RefsForApp). Before the fix they crash with the reported fatal error; after it
they pass, including under -race.

Validation run locally:

  • go test ./pkg/reftracker/... -race passes (existing + new tests)
  • gofmt / go vet clean
Review Checklist:
  • Follows the developer guidelines
  • Relevant tests are added or updated
  • Relevant docs in this repo added or updated (n/a, internal bug fix)
  • Relevant carvel.dev docs added or updated (n/a)
  • Code is at least as readable and maintainable as it was before this change

Signed-off-by: somaz <genius5711@gmail.com>
somaz94 added a commit to somaz94/somaz94 that referenced this pull request Jul 15, 2026
@somaz94
somaz94 marked this pull request as ready for review July 20, 2026 08:25
@somaz94

somaz94 commented Aug 10, 2026

Copy link
Copy Markdown
Author

@himsngh @praveenrewar — gentle ping on this one. It fixes a concurrent map iteration and map write panic in AppRefTracker.

Worth flagging: none of the test workflows have ever executed against it. 8 of the 9 runs on the head sha sit at action_required (test-gh, test-kctrl-gh, Kind Cluster E2E, golangci-lint, upgrade-testing, benchmarks, reviewdog, inclusive-language) — only "Add issues to project" ran, plus the Snyk statuses, so the check list looks greener than it is.

For a concurrency fix that's exactly the signal worth having. Could one of you approve the workflow run? Marking it ready for review on 20 Jul didn't re-dispatch them.

joaopapereira and others added 2 commits September 23, 2026 09:12
The tests now use t to check that the reader iterated at least one
result, and the AppsForRef writer adds and removes a second App, so the
set it writes to is never empty. With a single CPU the old writer left
the reader seeing only empty sets in about 2 of 100 runs, and the test
then passed without exercising the race.

Signed-off-by: somaz <genius5711@gmail.com>
@somaz94

somaz94 commented Sep 28, 2026

Copy link
Copy Markdown
Author

Thanks for merging develop in. The lint run that followed flagged my new race tests, and fa32fda fixes them. While fixing that I found the AppsForRef test could pass without exercising the race, because its writer sometimes left the reader with only empty sets, so the writer now adds and removes a second App and both tests check that the reader iterated something.

@somaz94

somaz94 commented Oct 29, 2026

Copy link
Copy Markdown
Author

Hi @joaopapereira, the lint failures from the run after your develop merge are fixed in fa32fda. The workflows on that head are waiting for approval to run, since the earlier approval expired. Could you approve them and take a look when you have time?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Follow-up on #1812: Race Condition in AppRefTracker (Concurrent Map Iteration and Write)

2 participants